// module ysyx_050369_pc_pre (
//     input          clk,
//     input          rst,
//     input          i_pc_stop,
//     input          i_call_valid,
//     input          i_ret_valid,
//     input   [31:0] i_if_pc,
//     input   [31:0] i_ex_pc,
//     input          i_jump_valid,
//     input   [31:0] i_nxpc,
//     input          i_pre_error,
//     output         o_jump_valid,
//     output  [31:0] o_pc_pre
// );
// wire [5:0]  ex_offset;
// wire [5:0]  if_offset;
// reg  [31:0] jup_pc  [63:0];//存放的是的可能会跳转的pc
// reg  [1:0]  pre     [63:0];
// reg  [31:0] pre_pc  [63:0]; 
// reg  [31:0] call_pc [63:0];
// reg  [31:0] jalr_pc [63:0];
// reg  [31:0] ret_pc  [63:0];
// reg  [31:0] fuc_pc  [31:0]; 
// reg  [4:0]  fuc_cnt;
// assign ex_offset = i_ex_pc[7:2];
// assign if_offset = i_if_pc[7:2];
// integer i;
// always @(posedge clk ) begin
//     if (rst) begin
//         for (i = 0; i< 64; i++ ) begin
//             jup_pc[i] <= 32'b0;
//             pre[i]    <=  2'b0;
//             pre_pc[i] <= 32'b0;
//         end
//         fuc_cnt <= 5'b0;
//     end
//     else if(~i_pc_stop) begin
//         if (i_pre_error ) begin
//             if (i_call_valid) begin
//                 fuc_pc [fuc_cnt]    <= i_ex_pc + 4;
//                 jalr_pc [ex_offset]  <= i_nxpc;
//                 call_pc [ex_offset] <= i_ex_pc;
//                 fuc_cnt             <= fuc_cnt+1;
//             end
//             else if (i_ret_valid) begin
//                 ret_pc [ex_offset] <= i_ex_pc;
//                 fuc_cnt            <= fuc_cnt-1;
//             end
//             else begin
//                 if (pre   [ex_offset] == 0) begin
//                     jup_pc[ex_offset] <= i_ex_pc;
//                     pre_pc[ex_offset] <= i_nxpc; 
//                     pre   [ex_offset] <= 2'b11;
//                 end
//                 else begin
//                     pre   [ex_offset] <= pre   [ex_offset] - 1;
//                 end
//             end
//         end
//         else if (i_jump_valid && ~i_call_valid && ~i_ret_valid) begin
//             if (pre   [ex_offset] < 2'b11) begin
//                 pre   [ex_offset] <= pre   [ex_offset] + 1;
//             end
//         end
//         if (i_if_pc == call_pc[if_offset] && i_if_pc != 'b0) begin
//             fuc_pc [fuc_cnt] <= i_if_pc + 4;
//             fuc_cnt          <= fuc_cnt+1;
//         end
//         else if (i_if_pc == ret_pc[if_offset] && i_if_pc != 'b0) begin
//             fuc_cnt          <= fuc_cnt-1;
//         end
//     end
// end

// assign o_jump_valid = (i_if_pc == call_pc[if_offset])? 1'b1 :(i_if_pc == ret_pc[if_offset])? 1'b1:(jup_pc[if_offset]==i_if_pc)&&(pre[if_offset]> 'b0);
// assign o_pc_pre = (i_if_pc == call_pc[if_offset])?jalr_pc[if_offset] :(i_if_pc == ret_pc[if_offset])? fuc_pc [fuc_cnt-1]:pre_pc[if_offset];

// endmodule

module ysyx_050369_pc_pre (
    input          clk,
    input          rst,
    input          i_pc_stop,
    input   [31:0] i_if_pc,
    input   [31:0] i_ex_pc,
    input          i_jump_valid,
    input   [31:0] i_nxpc,
    input          i_pre_error,
    output         o_jump_valid,
    output  [31:0] o_pc_pre
);
wire [5:0]  ex_offset;
wire [5:0]  if_offset;
reg  [31:0] jup_pc  [63:0];//存放的是的可能会跳转的pc
reg  [1:0]  pre     [63:0];
reg  [31:0] pre_pc  [63:0]; 
assign ex_offset = i_ex_pc[7:2];
assign if_offset = i_if_pc[7:2];
integer i;
always @(posedge clk ) begin
    if (rst) begin
        for (i = 0; i< 64; i++ ) begin
            jup_pc[i] <= 32'b0;
            pre[i]    <=  2'b0;
            pre_pc[i] <= 32'b0;
        end
    end
    else if(~i_pc_stop) begin
        if (i_pre_error ) begin
            if (pre   [ex_offset] == 0) begin
                jup_pc[ex_offset] <= i_ex_pc;
                pre_pc[ex_offset] <= i_nxpc; 
                pre   [ex_offset] <= 2'b11;
            end
            else begin
                pre   [ex_offset] <= pre   [ex_offset] - 1;
            end
        end
        else if (i_jump_valid ) begin
            if (pre   [ex_offset] < 2'b11 ) begin
                pre   [ex_offset] <= pre   [ex_offset] + 1;
            end
        end
    end
end

assign o_jump_valid =  (jup_pc[if_offset]==i_if_pc)&&(pre[if_offset] > 0);
assign o_pc_pre =  pre_pc[if_offset];

endmodule